
#region Using Statements

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using FamilyTreeProject.Framework.Entities;
using FamilyTreeProject.Framework.Collections;
using FamilyTreeProject.Data.Repositories;
using FamilyTreeProject.ComponentModel;


#endregion

namespace FamilyTreeProject.Framework.Collections.Proxies
{

    /// <summary>
    /// The ListProxyBase Class provides an abstract base class for all 
    /// List Proxies
    /// </summary>
    public abstract class ObjectCollectionProxy<TType> : IObjectCollection<TType> where TType : IObjectBase
    {

        #region Private Fields

        private int ownerId;
        private ObjectCollection<TType> innerCollection;
        private IFamilyTreeRepository repository;

        #endregion

        #region Constructors

        /// <summary>
        /// Constructs an ObjectCollectionProxy
        /// </summary>
        /// <param name="ownerId">The Id of the Object that owns this Collection Proxy</param>
        protected internal ObjectCollectionProxy(int ownerId)
        {
            this.ownerId = ownerId;
            this.repository = Container.GetService<IFamilyTreeRepository>();
        }

        /// <summary>
        /// Constructs an ObjectCollectionProxy
        /// </summary>
        /// <param name="ownerId">The Id of the Object that owns this Collection Proxy</param>
        /// <param name="repository">The IFamilyTreeRepository object to use.</param>
        protected internal ObjectCollectionProxy(int ownerId, IFamilyTreeRepository repository)
        {
            this.ownerId = ownerId;
            this.repository = repository;
        }

        #endregion

        #region Protected Properties

        /// <summary>
        /// The ObjectCollection that this collection proxies
        /// </summary>
        protected ObjectCollection<TType> InnerCollection
        {
            get
            {
                if (innerCollection == null) innerCollection = GetCollection();
                return innerCollection;
            }
        }

        /// <summary>
        /// The Repository that this proxy uses
        /// </summary>
        protected IFamilyTreeRepository Repository
        {
            get { return repository; }
        }

        #endregion

        #region Abstract Methods

        /// <summary>
        /// GetList gets the list
        /// </summary>
        /// <returns>IList<TProxy></returns>
        /// -----------------------------------------------------------------------------
        protected abstract ObjectCollection<TType> GetCollection();

        #endregion

        #region IObjectCollection<TType>

        /// <summary>
        /// Determines whether the colelction contains an item with the specified key
        /// </summary>
        /// <param name="key">The key to check</param>
        /// <returns>A bbolean that indicates whether the colelction contains the specifed key</returns>
        public bool ContainsKey(int key)
        {
            return InnerCollection.ContainsKey(key);
        }

        /// <summary>
        /// Gets the Lookup Dictionary
        /// </summary>
        public IDictionary<int, TType> Dictionary
        {
            get { return InnerCollection.Dictionary; }
        }

        /// <summary>
        /// Gets the coolection of Items
        /// </summary>
        public IList<TType> Items
        {
            get { return InnerCollection.Items; }
        }

        /// <summary>
        /// Gets and sets the Id of the Object that owns the collection
        /// </summary>
        /// <returns>The Id</returns>
        public int OwnerId
        {
            get { return ownerId; }
            set { ownerId = value; }
        }

        /// <summary>
        /// Removes the item with the specified Key
        /// </summary>
        /// <param name="key">The key of the item to remove</param>
        public void Remove(int key)
        {
            InnerCollection.Remove(key);
        }

        #endregion

        #region IList<TProxy> Members

        /// <summary>
        /// Gets the Index in the List of a specific item
        /// </summary>
        /// <param name="item">The item whose index is required</param>
        /// <returns>The index of the item</returns>
        public int IndexOf(TType item)
        {
            return InnerCollection.IndexOf(item);
        }

        /// <summary>
        /// Inserts an item at the specified index
        /// </summary>
        /// <param name="item">The item whose index is required</param>
        /// <param name="index">The index to insert the item at</param>
        public void Insert(int index, TType item)
        {
            InnerCollection.Insert(index, item);
        }

        /// <summary>
        /// Removes the specified item from the list
        /// </summary>
        /// <param name="index">The index of the item being removed</param>
        /// <returns>The index of the item</returns>
        public void RemoveAt(int index)
        {
            InnerCollection.RemoveAt(index);
        }

        /// <summary>
        /// Indexer for the List
        /// </summary>
        /// <param name="index">The index of the item</param>
        /// <returns>The item</returns>
        public TType this[int index]
        {
            get { return InnerCollection[index]; }
            set { InnerCollection[index] = value; }
        }

        #endregion

        #region ICollection<TType> Members

        /// <summary>
        /// Adds the specified item
        /// </summary>
        /// <param name="item">The item to be added</param>
        public void Add(TType item)
        {
            InnerCollection.Add(item);
        }

        /// <summary>
        /// Clears the List
        /// </summary>
        public void Clear()
        {
            InnerCollection.Clear();
        }

        /// <summary>
        /// Determines whether the List contains the specified item
        /// </summary>
        /// <param name="item">The item to be checked</param>
        /// <returns>A boolean indicating whether the item is the List</returns>
        public bool Contains(TType item)
        {
            return InnerCollection.Contains(item);
        }

        /// <summary>
        /// Copies the List to an Array, starting at a specified index position
        /// </summary>
        /// <param name="array">The array to use</param>
        /// <param name="arrayIndex">The arrayIndex to start at.</param>
        public void CopyTo(TType[] array, int arrayIndex)
        {
            InnerCollection.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// The number of items in the list
        /// </summary>
        /// <value>The number of items in the List</value>
        public int Count
        {
            get { return InnerCollection.Count; }
        }

        /// <summary>
        /// A flag indicating whther the List is ReadOnly
        /// </summary>
        /// <value>A boolean indicating whether the List is ReadOnly</value>
        public bool IsReadOnly
        {
            get { return false; }
        }

        /// <summary>
        /// Removes the specified item
        /// </summary>
        /// <param name="item">The item to be removed</param>
        public bool Remove(TType item)
        {
            return InnerCollection.Remove(item);
        }

        #endregion

        #region IEnumerable<TType> Members

        /// <summary>
        /// Gets an Enumerator for the List
        /// </summary>
        /// <returns>The enumerator (IEnumerator<TType>)</returns>
        public IEnumerator<TType> GetEnumerator()
        {
            return InnerCollection.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Gets an Enumerator for the List
        /// </summary>
        /// <returns>The enumerator (IEnumerator)</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return InnerCollection.GetEnumerator();
        }

        #endregion

    }
}
